/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.collections.comparators; import java.util.Arrays; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import java.util.Random; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; /** * Test class for FixedOrderComparator. * * @version $Revision: 646780 $ $Date: 2008-04-10 13:48:07 +0100 (Thu, 10 Apr 2008) $ * * @author David Leppik * @author Stephen Colebourne */ public class TestFixedOrderComparator extends TestCase { /** * Top cities of the world, by population including metro areas. */ public static final String topCities[] = new String[] { "Tokyo", "Mexico City", "Mumbai", "Sao Paulo", "New York", "Shanghai", "Lagos", "Los Angeles", "Calcutta", "Buenos Aires" }; // // Initialization and busywork // public TestFixedOrderComparator(String name) { super(name); } public static Test suite() { return new TestSuite(TestFixedOrderComparator.class); } public static void main(String args[]) { junit.textui.TestRunner.run(suite()); } // // Set up and tear down // // // The tests // /** * Tests that the constructor plus add method compares items properly. */ public void testConstructorPlusAdd() { FixedOrderComparator comparator = new FixedOrderComparator(); for (int i = 0; i < topCities.length; i++) { comparator.add(topCities[i]); } String[] keys = (String[]) topCities.clone(); assertComparatorYieldsOrder(keys, comparator); } /** * Tests that the array constructor compares items properly. */ public void testArrayConstructor() { String[] keys = (String[]) topCities.clone(); String[] topCitiesForTest = (String[]) topCities.clone(); FixedOrderComparator comparator = new FixedOrderComparator(topCitiesForTest); assertComparatorYieldsOrder(keys, comparator); // test that changing input after constructor has no effect topCitiesForTest[0] = "Brighton"; assertComparatorYieldsOrder(keys, comparator); } /** * Tests the list constructor. */ public void testListConstructor() { String[] keys = (String[]) topCities.clone(); List topCitiesForTest = new LinkedList(Arrays.asList(topCities)); FixedOrderComparator comparator = new FixedOrderComparator(topCitiesForTest); assertComparatorYieldsOrder(keys, comparator); // test that changing input after constructor has no effect topCitiesForTest.set(0, "Brighton"); assertComparatorYieldsOrder(keys, comparator); } /** * Tests addAsEqual method. */ public void testAddAsEqual() { FixedOrderComparator comparator = new FixedOrderComparator(topCities); comparator.addAsEqual("New York", "Minneapolis"); assertEquals(0, comparator.compare("New York", "Minneapolis")); assertEquals(-1, comparator.compare("Tokyo", "Minneapolis")); assertEquals(1, comparator.compare("Shanghai", "Minneapolis")); } /** * Tests whether or not updates are disabled after a comparison is made. */ public void testLock() { FixedOrderComparator comparator = new FixedOrderComparator(topCities); assertEquals(false, comparator.isLocked()); comparator.compare("New York", "Tokyo"); assertEquals(true, comparator.isLocked()); try { comparator.add("Minneapolis"); fail("Should have thrown an UnsupportedOperationException"); } catch (UnsupportedOperationException e) { // success -- ignore } try { comparator.addAsEqual("New York", "Minneapolis"); fail("Should have thrown an UnsupportedOperationException"); } catch (UnsupportedOperationException e) { // success -- ignore } } public void testUnknownObjectBehavior() { FixedOrderComparator comparator = new FixedOrderComparator(topCities); try { comparator.compare("New York", "Minneapolis"); fail("Should have thrown a IllegalArgumentException"); } catch (IllegalArgumentException e) { // success-- ignore } try { comparator.compare("Minneapolis", "New York"); fail("Should have thrown a IllegalArgumentException"); } catch (IllegalArgumentException e) { // success-- ignore } assertEquals(FixedOrderComparator.UNKNOWN_THROW_EXCEPTION, comparator.getUnknownObjectBehavior()); comparator = new FixedOrderComparator(topCities); comparator.setUnknownObjectBehavior(FixedOrderComparator.UNKNOWN_BEFORE); assertEquals(FixedOrderComparator.UNKNOWN_BEFORE, comparator.getUnknownObjectBehavior()); LinkedList keys = new LinkedList(Arrays.asList(topCities)); keys.addFirst("Minneapolis"); assertComparatorYieldsOrder(keys.toArray(new String[0]), comparator); assertEquals(-1, comparator.compare("Minneapolis", "New York")); assertEquals( 1, comparator.compare("New York", "Minneapolis")); assertEquals( 0, comparator.compare("Minneapolis", "St Paul")); comparator = new FixedOrderComparator(topCities); comparator.setUnknownObjectBehavior(FixedOrderComparator.UNKNOWN_AFTER); keys = new LinkedList(Arrays.asList(topCities)); keys.add("Minneapolis"); assertComparatorYieldsOrder(keys.toArray(new String[0]), comparator); assertEquals( 1, comparator.compare("Minneapolis", "New York")); assertEquals(-1, comparator.compare("New York", "Minneapolis")); assertEquals( 0, comparator.compare("Minneapolis", "St Paul")); } // // Helper methods // /** Shuffles the keys and asserts that the comparator sorts them back to * their original order. */ private void assertComparatorYieldsOrder(Object[] orderedObjects, Comparator comparator) { Object[] keys = (Object[]) orderedObjects.clone(); // shuffle until the order changes. It's extremely rare that // this requires more than one shuffle. boolean isInNewOrder = false; while (keys.length > 1 && isInNewOrder == false) { shuffle: { Random rand = new Random(); for (int i = keys.length-1; i > 0; i--) { Object swap = keys[i]; int j = rand.nextInt(i+1); keys[i] = keys[j]; keys[j] = swap; } } testShuffle: { for (int i = 0; i < keys.length && !isInNewOrder; i++) { if( !orderedObjects[i].equals(keys[i])) { isInNewOrder = true; } } } } // The real test: sort and make sure they come out right. Arrays.sort(keys, comparator); for (int i = 0; i < orderedObjects.length; i++) { assertEquals(orderedObjects[i], keys[i]); } } }